﻿Shader "Running/ScreenAO"
{
	Properties
	{
		_MainTex ("_MainTex", 2D) = "white" {}
		_normalDepth("_normalDepth", 2D) = "white" {}
	}

	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				float4 vertex : SV_POSITION;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;

			sampler2D _normalDepth;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				float4 mainColor = tex2D(_MainTex, i.uv);

				float4 oColor;
				// sample the texture
				//fixed4 col = tex2D(_MainTex, i.uv);
				//fixed4 normalDep = tex2D(_normalDepth, i.uv);
				//return col;
				
				//normalDepth的y反了
				float2 texCoord = i.uv;
				texCoord.y = 1 - texCoord.y;

				float4 normalDepth = tex2D(_normalDepth, texCoord);

				//xyz 法向量 w 深度 镜头空间
				if (normalDepth.z < 0.05) {
					oColor.rgba = float4(1.0, 1.0, 1.0, 1.0);

					return mainColor * oColor;
					//return oColor;
				}

				//-1 1 范围normal
				normalDepth.xyz = normalize(normalDepth.xyz * 2 - 1.0);

				const int samples = 4;
				//采样上下 左右 点
				float2 offsets[4] = {
					float2(-0.0 , 0.5),
					float2(0.0 ,-0.5),
					float2(-0.5 ,-0.0),
					float2(0.5 ,-0.0) };

				float totalMultiplier = 0.0;
				const float a = (1.0 / samples) * 1.0;
				const float a2 = a * 0.4;
				//采样上下 左右4个点  附近影响总的AO
				for (int i = 0; i < samples; ++i) {
					float2 t2 = offsets[i] * 0.004 * (1.0 - normalDepth.w) + texCoord;
					float4 sampledNormalDepth = tex2D(_normalDepth, t2);

					float depthDiff = (normalDepth.w - sampledNormalDepth.w);
					totalMultiplier += smoothstep(0.008, 0.015, abs(depthDiff)) * a2;
					sampledNormalDepth.xyz = normalize(sampledNormalDepth.xyz * 2.0 - 1.0);

					// make sampled normal z absolute: makes faked normals (billboards) appear as facing camera when sampled
					sampledNormalDepth.z = abs(sampledNormalDepth.z);

					float angleDiff = dot(normalDepth.xyz, sampledNormalDepth.xyz);
					totalMultiplier += (1.0 - max(angleDiff, 0.0)) * a;
				}

				totalMultiplier = min(totalMultiplier, 1.0);
				totalMultiplier = max(totalMultiplier, 0.0);

				totalMultiplier = 1.0 - totalMultiplier;

				//计算得到最终的AO只
				oColor.r = totalMultiplier;
				oColor.g = totalMultiplier;
				oColor.b = totalMultiplier;
				oColor.a = 1.0;


				return mainColor * oColor;
				//return oColor;
			}
			ENDCG
		}
	}
}
